/**
 * @ Author: luoqi
 * @ Create Time: 2024-03-14 10:53
 * @ Modified by: luoqi
 * @ Modified time: 2024-03-18 16:48
 * @ Description:
 */
#include "qsync.h"
#include "../algo/qstr.h"

static uint16_t _qsync_id_calcu(const char *name)
{
    uint16_t i = 0, id = 0;
    while(name[i] != '\0'){
        id += name[i];
        i ++;
    }
    return id;
}

int qsync_init(QSyncLink *sync, QSyncSend send, QSyncRecv recv)
{
    qmemset(sync, 0, sizeof(QSyncLink));
    qlist_init(&sync->sync_list);
    qlink_init(&sync->link, send, recv, sync->framebuf, QSYNC_BUF_SIZE, sync->rbuf, QSYNC_BUF_SIZE);

    return 0;
}

int qsync_topic_init(QSyncTopic *topic, const char *name, QSyncTopicCb callback)
{
    topic->topic = name;
    topic->id = _qsync_id_calcu(name);
    topic->callback = callback;
    return 0;
}

int qsync_topic_register(QSyncLink *sync, QSyncTopic *topic)
{
    sync->topic_num++;
    qlist_insert_after(&sync->sync_list, &topic->sync_node);
    return 0;
}

int qsync_send(QSyncLink *sync, const char *topic, uint8_t *data, uint8_t size)
{
    uint16_t id = _qsync_id_calcu(topic);
    sync->link.sframe.serial = ((id >> 8) & 0xff) - 1;
    return qlink_send(&sync->link, (id & 0xff), data, size);
}

int qsync_recv(QSyncLink *sync, int size)
{
    return qlink_recv(&sync->link, size);
}

int qsync_exec(QSyncLink *sync)
{
    uint16_t topic_id = ((uint16_t)sync->link.rframe.serial << 8) | sync->link.rframe.type;
    QList *_node;
    QSyncTopic *topic;
    QLIST_ITERATOR(_node, &sync->sync_list) {
        topic = QLIST_OBJ(_node, QSyncTopic, sync_node);
        if(topic->id == topic_id) {
            return topic->callback(sync->link.rframe.data, sync->link.rframe.size);
        } else {
            continue;
        }
    }
    return 0;
}
